package com.apobates.jforum.comments.core;

import com.apobates.jforum.comments.Comments;
import com.apobates.jforum.comments.CommentsRelations;
import com.apobates.jforum.comments.vo.ThreadsCommentsVo;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 传统的论坛显示模式
 * blockquote嵌套
 */
public class ForumStyleCommentsConverter implements CommentsConverter<ThreadsCommentsVo>{
    private final boolean paragraph;

    /**
     * 初始化
     *
     * 对内容进行p元素包装
     */
    public ForumStyleCommentsConverter() {
        this(true);
    }

    /**
     * 初始化
     *
     * @param paragraph 是否对内容进行p元素包装,true包装,false不包装
     */
    public ForumStyleCommentsConverter(boolean paragraph) {
        this.paragraph = paragraph;
    }

    @Override
    public List<ThreadsCommentsVo> map(List<Comments> rs, List<CommentsRelations> relations) {
        //都引用了哪些上次
        //4, 3,2,1
        //key=回复ID, val=引用的列表
        Map<Integer, TreeSet<Integer>> tree = new HashMap<>();
        for(CommentsRelations cr : relations){
            tree.put(cr.getCommentsId(), convert(cr.getSequence()));
        }
        //Step2
        Map<Comments, TreeSet<Comments>> data = new HashMap<>();
        for(Comments c : rs) {
            TreeSet<Comments> quotes = new TreeSet<>();
            if(tree.containsKey(c.getId())){
                quotes = getQuoteComments(rs, tree.get(c.getId()));
            }
            data.put(c, quotes);
        }
        //step3
        List<ThreadsCommentsVo> result = new ArrayList<>();
        for (Map.Entry<Comments, TreeSet<Comments>> entry : data.entrySet()){
            Comments currentFloor = entry.getKey();
            TreeSet<Comments> quoteFloor = entry.getValue();
            result.add(new ThreadsCommentsVo(currentFloor.getId(), currentFloor.getUser(), getQuoteContent(currentFloor.getContent(), quoteFloor)));
        }
        return result;
    }

    /**
     * 获取引用的评论树
     *
     * @param source 评论
     * @param quoteCommentIds 评论引用序列
     * @return
     */
    private TreeSet<Comments> getQuoteComments(List<Comments> source, TreeSet<Integer> quoteCommentIds){
        TreeSet<Comments> quoteComments = new TreeSet<>();
        Iterator<Integer> iterator = quoteCommentIds.iterator();
        while (iterator.hasNext()){
            final Integer cid = iterator.next();
            Optional<Comments> first = source.stream().filter(c -> cid.compareTo(c.getId()) == 0).findFirst();
            if(first.isPresent()){
                quoteComments.add(first.get());
            }
        }
        return quoteComments;
    }

    /**
     * 将评论的引用关系转成引用的评论ID集合
     *
     * @param commentIds
     * @return
     */
    private TreeSet<Integer> convert(String commentIds){
        return Stream.of(commentIds.split(",")).map(Integer::valueOf).collect(
                Collectors.toCollection(TreeSet::new)
        );
    }

    /**
     * 返回增加blockquote元素的评论内容
     *
     * @param replyContent
     * @param quoteFloor
     * @return
     */
    private String getQuoteContent(String replyContent, TreeSet<Comments> quoteFloor){
        if(quoteFloor.isEmpty()){
            return paragraph(replyContent);
        }
        //引用模板
        String template = "<blockquote cite=\"%s\">%s</blockquote>";
        //引用:xiaofanku在x楼的回复
        String citeTemplate = "引用:%s在%d楼的回复";
        //<blockquote cite="3">
        //      <blockquote cite="2">
        //          <blockquote cite="1">
        //              <p>1</p>
        //          </blockquote>
        //          <p>2</p>
        //      </blockquote>
        //      <p>3</p>
        //</blockquote>
        String sb =null;
        Iterator<Comments> it = quoteFloor.iterator();
        while (it.hasNext()){
            Comments tmp = it.next();
            String citeStr = String.format(citeTemplate, tmp.getUser(), tmp.getFloor());
            String quoteContent = paragraph(tmp.getContent());
            if(sb!=null) {
                quoteContent = sb + paragraph(tmp.getContent());
            }
            sb = String.format(template, citeStr, quoteContent);
        }
        return sb+paragraph(replyContent);
    }

    private String paragraph(String content){
        if(!paragraph){
            return content;
        }
        return "<p>"+content+"</p>";
    }
}
